package drds.server.execute_engine.data_handling.model;

import java.util.ArrayList;
import java.util.List;

import drds.server.net.packet.RowDataPacket;
import drds.server.route.RouteNode;

public class NodeRowDataPacket {

	private RouteNode node;
	private long trimTotal = 0;

	private int trimSize = 0;

	private List<RangRowDataPacket> trimRangRDPacketList = new ArrayList<RangRowDataPacket>();
	private List<RangRowDataPacket> rangRowDataPacketList = new ArrayList<RangRowDataPacket>();

	public NodeRowDataPacket(RouteNode node, int trimSize) {
		this.node = node;
		this.trimSize = trimSize;
	}

	public void newRangRowDataPacket() {
		RangRowDataPacket rangRowDataPacket = new RangRowDataPacket();
		rangRowDataPacketList.add(rangRowDataPacket);
	}

	public long loadTotal() {
		return this.loadTrimTotal() + this.loadNotTrimTotal();
	}

	public long loadTrimTotal() {
		this.trimTotal = 0;
		for (RangRowDataPacket rangRowDataPacket : trimRangRDPacketList) {
			if (rangRowDataPacket.isTrim()) {
				this.trimTotal += rangRowDataPacket.allSize();
			}
		}
		return this.trimTotal;
	}

	public long loadNotTrimTotal() {
		long total = 0;
		for (RangRowDataPacket rangRowDataPacket : rangRowDataPacketList) {
			total += rangRowDataPacket.allSize();
		}
		return total;
	}

	public void moveToTrim() {
		RangRowDataPacket head = this.loadHeadPacket();
		if (head != null && this.rangRowDataPacketList.remove(head)) {
			this.trimRangRDPacketList.add(head);
			if (head.allSize() == this.trimSize) {
				head.leftHeadTail();
			}
		}
	}

	public void moveHeadTail3ToTrim() {
		if (this.rangRowDataPacketList.size() >= 3) {
			int m = 0;
			while ((m = this.rangRowDataPacketList.size()) > 3) {
				RangRowDataPacket packet = this.rangRowDataPacketList.remove(0);
				if (packet.allSize() == this.trimSize) {
					packet.leftHeadTail();
				}
				addTrimWithCombine(packet);
			}

		}
	}

	private void addTrimWithCombine(RangRowDataPacket packet) {
		if (packet.allSize() == this.trimSize) {
			if (this.trimRangRDPacketList.isEmpty()) {
				this.trimRangRDPacketList.add(packet);
			} else {
				int last = this.trimRangRDPacketList.size() - 1;
				RangRowDataPacket lastPacket = this.trimRangRDPacketList.get(last);
				if (lastPacket.isTrim()) {
					lastPacket.combine(packet);
				} else {
					// 异常
				}
			}
		}
	}

	public void moveAllToTrim() {
		int m = 0;
		while ((m = this.rangRowDataPacketList.size()) > 0) {
			RangRowDataPacket packet = this.rangRowDataPacketList.remove(0);
			if (packet.getRowDataPacketList().size() == this.trimSize) {
				packet.leftHeadTail();
			}
			addTrimWithCombine(packet);
		}
	}

	public void add(RowDataPacket rowDataPacket) {
		RangRowDataPacket rangRowDataPacket = rangRowDataPacketList.get(rangRowDataPacketList.size() - 1);
		rangRowDataPacket.add(rowDataPacket);
	}

	public RouteNode getNode() {
		return node;
	}

	public List<RowDataPacket> loadData() {
		List<RowDataPacket> rowDataPacketList = new ArrayList<RowDataPacket>();
		for (RangRowDataPacket rangRowDataPacket : rangRowDataPacketList) {
			rowDataPacketList.addAll(rangRowDataPacket.getRowDataPacketList());
		}
		for (RangRowDataPacket packet : trimRangRDPacketList) {
			if (!packet.isTrim()) {
				rowDataPacketList.addAll(packet.getRowDataPacketList());
			}
		}
		return rowDataPacketList;
	}

	public RangRowDataPacket loadHeadPacket() {
		if (rangRowDataPacketList != null && !rangRowDataPacketList.isEmpty()) {
			return rangRowDataPacketList.get(0);
		}
		return null;
	}

	public RangRowDataPacket loadTailPacket() {
		return this.loadTailPacket(1);
	}

	public RangRowDataPacket loadTailPacket(int tailIndex) {
		int size = rangRowDataPacketList.size() - tailIndex;
		if (size >= 0) {
			return rangRowDataPacketList.get(size);
		}
		return null;
	}

}